package com.gree.changying.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Environment;
import android.util.Log;

import com.gree.changying.App;
import com.gree.changying.R;
import com.gree.changying.server.utils.DateUtil;
import com.gree.changying.server.utils.MD5;
import com.gree.changying.server.utils.NLog;
import com.gree.changying.server.utils.photo.ImageUtil;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 文件处理
 * 文件夹目录说明
 * temp_images 未上传到服务器中的本地照片
 * facecache 刷脸登录临时缓存
 * upload_images 已上传到服务器中的本地存储照片
 *
 */
public class FileUtil {
	private static final String TAG = "FileUtil";
	private static String parentPath;
	private static String storagePath = "";
	public static final String DST_FOLDER_NAME = "media";
	//旧版本使用是此路径，如果服务端有使用此路径的需要进行转换
	public static final String oldPath = Environment.getExternalStorageDirectory().getAbsolutePath();
	public static void getInstance(Context context){
		if(parentPath==null){
			parentPath = context.getFilesDir().getAbsolutePath();
		}
	}
	/**
	 * 获得一个欲存储的临时图片完整路径
	 * @return
	 */
	public static String getAImageFullPath(){
		return getAImageFullPath(null);
	}

	/**
	 * 获取完整的视频路径
	 * @return
	 */
	public static String getFullVideoPath(){
		String p= getPath()+"/video/";
		String date = DateUtil.format(new Date(),"yyyyMMdd");
		p+=date+"/";
		File mImageFile = new File(p);
		if(!mImageFile.exists()){
			mImageFile.mkdirs();
		}
		String path = mImageFile.getAbsoluteFile()+"/"+ UUID.randomUUID().toString() + ".mp4";
		return path;
	}
	public static String getAImagePath(String name){
		String p= getPath()+"/images/";
		File mImageFile = new File(p);
		if(!mImageFile.exists()){
			mImageFile.mkdirs();
		}
		String path = mImageFile.getAbsoluteFile()+"/"+name + ".jpg";
		return path;
	}
	public static String getAImageFullPath(String cname){
		String p= getPath()+"/images/";
		if(cname!=null){
			p+=cname+"/";
		}
		String date = DateUtil.format(new Date(),"yyyyMMdd");
		p+=date+"/";
		File mImageFile = new File(p);
		if(!mImageFile.exists()){
			mImageFile.mkdirs();
		}
		String path = mImageFile.getAbsoluteFile()+"/"+ UUID.randomUUID().toString() + ".jpg";
		return path;
	}

	/**
	 * 保存刷脸图片
	 * @param b
	 * @return
	 */
	public static String saveFaceBitmap(Bitmap b){
		String path = getPath()+"/face";
        File f = new File(path);
		if(!f.exists()){
			f.mkdir();
		}
		long dataTake = System.currentTimeMillis();
		String jpegName = path + "/" + dataTake +".jpg";
		Log.i(TAG, "saveBitmap:jpegName = " + jpegName);
		try {
			FileOutputStream fout = new FileOutputStream(jpegName);
			BufferedOutputStream bos = new BufferedOutputStream(fout);
			b.compress(Bitmap.CompressFormat.JPEG, 80, bos);
			bos.flush();
			bos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return jpegName;
	}

	/**
	 * 保存图片
	 * @param path
	 * @param b
	 * @return
	 */
	public static String saveBitmap(String path, Bitmap b){
		String p = "";
		if(path.contains("/")){
			p = path.substring(0,path.lastIndexOf("/"));
			File f = new File(p);
			if(!f.exists()){
				f.mkdirs();
			}
		}
		try {
			FileOutputStream fout = new FileOutputStream(path);
			BufferedOutputStream bos = new BufferedOutputStream(fout);
			b.compress(Bitmap.CompressFormat.JPEG, 80, bos);
			bos.flush();
			bos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return path;
	}
	public static String getPath(){
		if(StringUtil.isEmpty(storagePath)){
			if(parentPath==null){
				parentPath = App.getApp().getFilesDir().getAbsolutePath();
			}
			storagePath = parentPath+"/" + DST_FOLDER_NAME;
			File f = new File(storagePath);
			if(!f.exists()){
				f.mkdir();
			}
		}
		return storagePath;
	}
	public static String getTempPath(){
		String path = getPath()+"/temp";
		File f = new File(path);
		if(!f.exists()){
			f.mkdir();
		}
		return path;
	}

	/**
	 * 删除文件
	 * @param path
	 * @return
	 */
	public static boolean removeFile(String path){
		if(!StringUtil.isEmpty(path)){
			File file = new File(path);
			if(file.exists()){
				NLog.d("removeFile",path);
				return file.delete();
			}
		}
		return false;
	}

	/**
	 * 删除文件夹
	 * @param path
	 * @return
	 */
	public static void removeDir(String path){
		File file = new File(path);
		if(!file.exists()){
			return;
		}
		//文件名称列表
		String[] filePath = file.list();
		if(filePath==null){
			return;
		}
		for (int i = 0; i < filePath.length; i++) {
			File temp =new File(path + file.separator + filePath[i]);
			if (temp.isDirectory()) {
				removeDir(path  + file.separator  + filePath[i]);
			}
			temp.delete();
		}
		file.delete();
	}

	/**
	 * 判断文件是否存在
	 * @param path
	 * @return
	 */
	public static boolean checkFileExists(String path){
		if(path==null){
			return false;
		}
		File file = new File(path);
		return file.exists();
	}

	/**
	 *  复制整个文件夹
	 * @param oldPath
	 * @param newPath
	 */
	public static void copyDir(String oldPath, String newPath) throws IOException {
		File file = new File(oldPath);
		if(!file.exists()){
			return;
		}
		//文件名称列表
		String[] filePath = file.list();
		if(filePath==null){
			return;
		}
		if (!(new File(newPath)).exists()) {
			(new File(newPath)).mkdir();
		}
		for (int i = 0; i < filePath.length; i++) {
			if ((new File(oldPath + file.separator + filePath[i])).isDirectory()) {
				copyDir(oldPath  + file.separator  + filePath[i], newPath  + file.separator + filePath[i]);
			}

			if (new File(oldPath  + file.separator + filePath[i]).isFile()) {
				copyFile(oldPath + file.separator + filePath[i], newPath + file.separator + filePath[i]);
			}
		}
	}
	public static void copyFile(String oldPath, String newPath) throws IOException {
		File oldFile = new File(oldPath);
		File file = new File(newPath);
		FileInputStream in = new FileInputStream(oldFile);
		FileOutputStream out = new FileOutputStream(file);
		byte[] buffer=new byte[2097152];
		while((in.read(buffer)) != -1){
			out.write(buffer);
		}
	}
	//从assets复制文件到指定位置
	public static void copyFilesFromAssets(Context context, String oldPath, String newPath) {
		try {
			String[] fileNames = context.getAssets().list(oldPath);
			//NLog.e("fsdgsdfsdf",JsonMananger.beanToJsonStr(fileNames));
			if (fileNames.length > 0) {
				// directory
				File file = new File(newPath);
				if (!file.mkdirs()) {
					Log.d("mkdir", "can't make folder");
				}
//                    return false;                // copy recursively
				for (String fileName : fileNames) {
					copyFilesFromAssets(context, oldPath + "/" + fileName,
							newPath + "/" + fileName);
				}
			} else {
				// file
				InputStream is = context.getAssets().open(oldPath);
				FileOutputStream fos = new FileOutputStream(new File(newPath));
				byte[] buffer = new byte[1024];
				int byteCount;
				while ((byteCount = is.read(buffer)) != -1) {
					fos.write(buffer, 0, byteCount);
				}
				fos.flush();
				is.close();
				fos.close();
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}



	/**
	 *  打印日志
	 * @param map
	 * @return
	 */
	public static String printMap(Map<String, String> map){
		String txt = "";
		for(String key:map.keySet()){
			txt+=map.get(key)+"\n";
		}
		return txt;
	}
	/**
	 *  获取异常文本
	 * @param context
	 */
	public static Map<String, String> getCrash(Context context){
		return getCrash(context,false);
	}

	/**
	 * 读取数据
	 * @param var0
	 * @return
	 */
	public static byte[] readFileContents(String var0) {
		try {
			File var5;
			if (!(var5 = new File(var0)).exists()) {
				return null;
			} else {
				FileInputStream var6 = new FileInputStream(var5);
				byte[] var1 = new byte[1024];
				ByteArrayOutputStream var2 = new ByteArrayOutputStream();
				boolean var3 = false;
				int var7;
				while((var7 = var6.read(var1)) != -1) {
					var2.write(var1, 0, var7);
				}

				var2.close();
				var6.close();
				return var2.toByteArray();
			}
		} catch (Throwable var4) {
			return null;
		}
	}

	/**
	 * 获取异常文本
	 * @param context
	 * @param removeDup 是否去重
	 * @return
	 */
	public static Map<String, String> getCrash(Context context, boolean removeDup){
		String appname = context.getResources().getString(R.string.app_name);
		String pkg = context.getPackageName();
		Map<String, String> map = new HashMap<>();
		List<String> hashs = new ArrayList<>();
		Map<String, Integer> times = new HashMap<>();
		if(!checkHasCrash(context)){
			return map;
		}
		String path = context.getFilesDir()+"/tombstones";
		File file = new File(path);
		String[] filelist = file.list();
		int move = 0 ;
		for (int i = filelist.length-1; i>=0 ; i--) {
			File readfile = new File(path + "//" + filelist[i]);
			if(readfile.isFile()){
				byte[] bytes = readFileContents(readfile.getPath());
				String txt = new String(bytes);
				if(txt.contains("tail end of log main")){
					txt = txt.substring(0,txt.indexOf("tail end of log main"));
				}
				txt = txt.replaceAll("\\*\\*\\*","---");
				txt = txt.replaceAll("Tombstone maker","Create by");
				txt = txt.replaceAll("xCrash 2.4.9",appname);
				txt = txt.replaceAll("logcat:",">>end");

				String md5 = "";
				if(removeDup){
					String c = txt.replaceAll(" ","");
					c=c.replaceAll("\\n","");
					String left = pkg+"<<<";
					int start  =c.indexOf(left);
					String startStr = c.substring(start+left.length(),c.indexOf(">>end"));
					if(startStr.length()>1000){
						startStr = c.substring(start+left.length(),start+left.length()+1000);
					}
					md5 = MD5.encrypt(startStr);
					boolean hasHash = false;
					Integer time = times.get(md5);
					if(time==null){
						time=1;
					}
					for(String hash :hashs){
						if(hash.equals(md5)){
							hasHash = true;
							time++;
							break;
						}
					}
					times.put(md5,time);
					if(hasHash){
						move++;
						continue;
					}
					hashs.add(md5);
				}
				txt = "第" + (filelist.length - i-move) + "条异常信息"+":\n"
						+(removeDup?"特征码:"+md5+"\n":"")
						+ txt;
				map.put(md5,txt);
			}
		}

		if(removeDup) {
			for (String key : times.keySet()) {
				Integer time = times.get(key);
				String txt = map.get(key);
				if(!StringUtil.isEmpty(txt)){
					txt = txt.replaceAll(key, key + "[出现" + time + "次]");
					map.put(key,txt);
				}
			}
		}
		return map;
	}

	/**
	 * 获取日志路径
	 * @param context
	 * @return
	 */
	public static String[] getCrashPath(Context context){
		if(!checkHasCrash(context)){
			return null;
		}
		String path = context.getFilesDir()+"/tombstones";
		File file = new File(path);
		String[] filelist = file.list();
		 return filelist;
	}

	/**
	 * 判断是否有异常捕获
	 * @param context
	 * @return
	 */
	public static boolean checkHasCrash(Context context){
		String path = context.getFilesDir()+"/tombstones";
		boolean has =  FileUtil.checkFileExists(path);
		if(has){
			File file = new File(path);
			if(file.isDirectory()){
				String[] filelist = file.list();
				return  filelist.length>0;
			}
		}
		return false;
	}

	/**
	 *  清空crash
	 * @param context
	 */
	public static void cleanCrash(Context context){
		if(!checkHasCrash(context)){
			return;
		}
		String path = context.getFilesDir()+"/tombstones";
		File file = new File(path);
		String[] filelist = file.list();
		for (int i = 0; i < filelist.length; i++) {
			File readfile = new File(path + "//" + filelist[i]);
			if(readfile.isFile()){
				removeFile(readfile.getPath());
			}
		}
	}

	public static String getDownloadPath(){
		String path = Environment.getExternalStoragePublicDirectory(
				Environment.DIRECTORY_DOWNLOADS) + "/com.gree.shyun/newversion";
		File file = new File(path);
		if(!file.exists()){
			file.mkdirs();
		}
		return path;
	}
}
